package com.homedo.microservice.open.service.gateway.zuul.task;


import com.google.common.collect.Lists;
import com.homedo.common.util.Detect;
import com.homedo.microservice.open.service.gateway.bean.enums.forzuulfilter.ProgressEnum4ZuulFilter;
import com.homedo.microservice.open.service.gateway.bean.enums.forzuulfilter.StatusEnum4ZuulFilter;
import com.homedo.microservice.open.service.gateway.bean.enums.forzuulfilterdefault.ProgressEnum4ZuulFilterDefault;
import com.homedo.microservice.open.service.gateway.bean.enums.forzuulfilterdefault.StatusEnum4ZuulFilterDefault;
import com.homedo.microservice.open.service.gateway.bean.po.enhanced.ZuulFilterDefaultEnhanced;
import com.homedo.microservice.open.service.gateway.bean.po.enhanced.ZuulFilterEnhanced;
import com.homedo.microservice.open.service.gateway.service.ZuulFilterDefaultService;
import com.homedo.microservice.open.service.gateway.service.ZuulFilterService;
import com.homedo.microservice.open.service.gateway.zuul.conf.ZuulCommonConf;
import com.homedo.microservice.open.service.gateway.zuul.conf.ZuulFilterActiveConf;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

import java.util.List;
import java.util.stream.Collectors;

@Component
public class ZuulFilterActiveConfUpdateTask {
    @Autowired
    private ZuulFilterService zuulFilterService;
    @Autowired
    private ZuulCommonConf zuulCommonConf;
    @Autowired
    private ZuulFilterDefaultService zuulFilterDefaultService;

    private static final Logger LOGGER = LoggerFactory.getLogger(ZuulFilterActiveConfUpdateTask.class);

    @Scheduled(cron = "0/6 * * * * ?")
    public void ZuulFilterActiveConfUpdateTask() {
        StopWatch stopWatch = null;
        if (zuulCommonConf.getApplicationLogDetail().get()) {
            stopWatch = new StopWatch();
            stopWatch.start();
            LOGGER.info("更新正在运行的过滤器开始:时间[" + new DateTime().toString("yyyy-MM-dd HH:mm:ss.SSS") + "]");
        }

        this.doSchedule();

        if (zuulCommonConf.getApplicationLogDetail().get()) {
            if (stopWatch != null) {
                stopWatch.stop();
                LOGGER.info("更新正在运行的过滤器结束:时间[" + new DateTime().toString("yyyy-MM-dd HH:mm:ss.SSS") + "],耗时[" + stopWatch.getTotalTimeMillis() + "毫秒]");
            }
        }
    }

    private void doSchedule() {

        List<ProgressEnum4ZuulFilter> progresses = Lists.newArrayList(ProgressEnum4ZuulFilter.PUBLISHED);
        List<ProgressEnum4ZuulFilterDefault> progressesDefault = Lists.newArrayList(ProgressEnum4ZuulFilterDefault.PUBLISHED);
        if (zuulCommonConf.getZuulUseCanaryFilters().get()) {
            progresses.add(ProgressEnum4ZuulFilter.CANARY);
            progressesDefault.add(ProgressEnum4ZuulFilterDefault.CANARY);
        }

        List<ZuulFilterEnhanced> zuulFilterEnhanceds = zuulFilterService.getEnhanceds4Application(zuulCommonConf.getApplicationName(), progresses, Lists.newArrayList(StatusEnum4ZuulFilter.EFFECTIVE), null);

        List<String> activeFilterNames = Lists.newArrayList();
        if (Detect.notEmpty(zuulFilterEnhanceds)) {
            zuulFilterEnhanceds.forEach(e -> {
                activeFilterNames.addAll(zuulFilterEnhanceds.stream().map(ZuulFilterEnhanced::getFilterName).collect(Collectors.toList()));
            });
        }

        List<ZuulFilterDefaultEnhanced> zuulFilterDefaultEnhanceds = zuulFilterDefaultService.getEnhanceds4Application(zuulCommonConf.getApplicationName(), progressesDefault, Lists.newArrayList(StatusEnum4ZuulFilterDefault.EFFECTIVE), null);

        if (Detect.notEmpty(zuulFilterDefaultEnhanceds)) {
            zuulFilterDefaultEnhanceds.forEach(e -> {
                activeFilterNames.addAll(zuulFilterDefaultEnhanceds.stream().map(ZuulFilterDefaultEnhanced::getFilterName).collect(Collectors.toList()));
            });
        }

        ZuulFilterActiveConf.getInstance().setActiveFilterNames(activeFilterNames);

    }


}
